﻿using System.Collections;
using System.Threading;
using System.Runtime.InteropServices;
using System;
using System.IO;
using System.Collections.Generic;

     public class NetWorkToServer
    {
        private Thread thread2;
        private string ip;
        private int port;
        public static MySocket mySocket;
        private static Thread thread;
        public static ArrayList get_MessageDataPoolAL;//接受消息队列
        public static ArrayList send_MessageDataPoolAL;//发送消息队列
        private Hashtable packageCount;
        private Hashtable packageData;

        private static int EndFlag = 0xEE;//消息中的结束标记
        private static int SameEndFlag = 0x00;// 如果消息中存在和结束标记一样的字符则在最后加0x00

         /// <summary>
         /// 不断处理接收后缓存的数据
         /// </summary>
        void Update()
        {
            if (get_MessageDataPoolAL != null && get_MessageDataPoolAL.Count != 0)
            {
                try
                {
                    AnalyseData((byte[])get_MessageDataPoolAL[0]);

                }
                catch (Exception e)
                {
                    Console.WriteLine(e.ToString());
                }
                get_MessageDataPoolAL.RemoveAt(0);
            }
        }

        void Awake()
        {
            mySocket = new MySocket();
            send_MessageDataPoolAL = new ArrayList();
            packageData = new Hashtable();
            packageCount = new Hashtable();
        }

        public void Connect()
        {
            thread2 = new Thread(AysConnect);
            thread2.Start();
        }
        public void ConnectEX(string ip, int port)
        {
            this.ip = ip;
            this.port = port;
            thread2 = new Thread(AysConnect);
            thread2.Start();
        }
        void AysConnect()
        {
            mySocket.Async_Connect(this.ip, this.port, CallBack_Connect, CallBack_Receive);
        }

        /// <summary>
        /// 连接回调
        /// </summary>
        void CallBack_Connect(bool s, MySocket.Erro_Socket errorcode, string exception)
        {
            if (errorcode == MySocket.Erro_Socket.SUCCESS)
            {
                thread = new Thread(LoopSendMessage);
                thread.Start();
                Console.WriteLine("connOK");
            }
            else
            {
                Console.WriteLine("CallBack_Connect" + s + errorcode.ToString() + exception);
            }
        }
         /// <summary>
         /// 发送回调
         /// </summary>
        void CallBack_Send(bool s, MySocket.Erro_Socket errorcode, string exception)
        {
            if (errorcode != MySocket.Erro_Socket.SUCCESS)
            {
                Console.WriteLine("CallBack_Send" + s + errorcode.ToString() + exception);
            }
        }
         /// <summary>
         /// 接收回调
         /// </summary>
         void CallBack_Receive(bool s, MySocket.Erro_Socket errorcode, string exception, byte[] byteMessage, string strMessage)
         {
             if (errorcode != MySocket.Erro_Socket.SUCCESS)
             {
                 Console.WriteLine("CallBack_Receive" + s + errorcode.ToString() + exception + strMessage);
             }
             else
             {
                 PutGetMessageToPool(byteMessage);
             }
         }

         /// <summary>
         /// 不断处理发送后缓存的数据
         /// </summary>
        void LoopSendMessage()
        {
            while (mySocket != null && mySocket.IsConnect())
            {
                if (send_MessageDataPoolAL != null && send_MessageDataPoolAL.Count != 0)
                {
                    mySocket.Async_Send((byte[])send_MessageDataPoolAL[0], CallBack_Send);
                    send_MessageDataPoolAL.RemoveAt(0);
                }
                Thread.Sleep(20);
            }
        }

        public static void SendMessage(ByteArrayEx bytes)
        {
            PutMessageToPool(bytes);
        }
        /// <summary>
        /// 发送消息入池！
        /// </summary>
        public static void PutMessageToPool(ByteArrayEx bytes)
        {
            if (send_MessageDataPoolAL == null)
            {
                send_MessageDataPoolAL = new ArrayList();
            }
            send_MessageDataPoolAL.Add(PackageMyMessage(bytes));
            Console.WriteLine("poolCall:" + send_MessageDataPoolAL.Count);
        }

        /// <summary>
        /// 打包发送消息约定格式
        /// 处理发送的字符串存在0xEE的问题,以及约定以双0xEE作为结束
        /// </summary>
         public static byte[] PackageMyMessage(ByteArrayEx bytes)
        {
             bytes.position = 0;
			//检查到0xEE	就在后面加0x00,
			while(bytes.bytesAvailable != 0){
                if (bytes.readByte().ToString() == EndFlag.ToString())
                {
                    ByteArrayEx bt = new ByteArrayEx();
                    bt.writeBytes(bytes.byteArray, 0, bytes.position);
                    bt.writeBytes(ByteArrayTool.intToByte(SameEndFlag));
                    bt.writeBytes(bytes.byteArray, bytes.position, bytes.bytesAvailable);
                    bt.position = bytes.position;
                    bytes = bt;
				}
			}
            bytes.position = bytes.length;
            bytes.writeBytes(ByteArrayTool.intToByte(EndFlag));
            bytes.writeBytes(ByteArrayTool.intToByte(EndFlag));

            return bytes.byteArray;
        }

        /// <summary>
        /// 收到消息入池！
        /// </summary>
        /// <param name="get_Message"></param>
        public static void PutGetMessageToPool(int type1, int type2, byte[] message)
        {
            byte[] get_Message = new byte[20 + message.Length];

            MySocket.MemCpy(get_Message, ByteArrayTool.intToByte(get_Message.Length), 0, 4);
            MySocket.MemCpy(get_Message, ByteArrayTool.intToByte(type1), 4, 4);
            MySocket.MemCpy(get_Message, ByteArrayTool.intToByte(type2), 8, 4);
            MySocket.MemCpy(get_Message, message, 20, message.Length);
            if (get_MessageDataPoolAL == null)
            {
                get_MessageDataPoolAL = new ArrayList();
            }
            get_MessageDataPoolAL.Add(get_Message);
        }
        /// <summary>
        /// 收到消息入池！
        /// </summary>
        /// <param name="get_Message"></param>
        void PutGetMessageToPool(byte[] get_Message)
        {
            if (get_MessageDataPoolAL == null)
            {
                get_MessageDataPoolAL = new ArrayList();
            }
            get_MessageDataPoolAL.Add(get_Message);
        }

        /// <summary>
        /// 数据处理
        /// </summary>
        // <param name="byteMessage"></param>
        void AnalyseData(byte[] byteMessage)
        {
            byte[] byteTMP = new byte[4];
            MySocket.MemCpy(byteTMP, byteMessage, 0, 4);
            int dataLength = ByteArrayTool.byteToInt(byteTMP);//文件长度

            MySocket.MemCpy(byteTMP, byteMessage, 0, 4, 4);
            int dataType1 = ByteArrayTool.byteToInt(byteTMP);//文件主ID1

            MySocket.MemCpy(byteTMP, byteMessage, 0, 8, 4);
            int dataType2 = ByteArrayTool.byteToInt(byteTMP);//文件主ID2

            MySocket.MemCpy(byteTMP, byteMessage, 0, 12, 4);
            int codeID = ByteArrayTool.byteToInt(byteTMP);//文件主codeID

            byte[] messageData = new byte[dataLength - 20];
            MySocket.MemCpy(messageData, byteMessage, 0, 20, dataLength - 20);
            if (codeID > 1)
            {
                if (!packageCount.ContainsKey((int)dataType1 + "_" + (int)dataType2))//首次，最大包数
                {
                    packageCount.Add((int)dataType1 + "_" + (int)dataType2, codeID);
                }

                if (!packageData.ContainsKey((int)dataType1 + "_" + (int)dataType2 + "_" + codeID))
                {
                    packageData.Add((int)dataType1 + "_" + (int)dataType2 + "_" + codeID, messageData);
                }
                return;
            }
            else if (codeID == 1)
            {
                if (!packageData.ContainsKey((int)dataType1 + "_" + (int)dataType2 + "_" + codeID))
                {
                    packageData.Add((int)dataType1 + "_" + (int)dataType2 + "_" + codeID, messageData);
                }
                int count = 0;
                if (packageCount.ContainsKey((int)dataType1 + "_" + (int)dataType2))//首次，最大包数
                {
                    count = (int)packageCount[(int)dataType1 + "_" + (int)dataType2];
                }
                int offset = 0;
                int messageLength = 0;

                for (int a = 0; a < count; ++a)
                {
                    messageLength += ((byte[])packageData[(int)dataType1 + "_" + (int)dataType2 + "_" + (a + 1)]).Length;
                }
                if (messageLength != 0)
                {

                    messageData = new byte[messageLength];
                    for (int a = 0; a < count; ++a)
                    {
                        byte[] byteTmp = (byte[])packageData[(int)dataType1 + "_" + (int)dataType2 + "_" + (count - a)];
                        MySocket.MemCpy(messageData, byteTmp, offset);
                        offset += byteTmp.Length;
                    }
                    packageCount.Clear();
                    packageData.Clear();
                }
            }
            //IsLoginOk = (dataLength - 20);
            Console.WriteLine("ID1:  " + (int)dataType1 + "        ID2:  " + (int)dataType2 + "      dataLength:" + (dataLength - 20));
            switch (dataType1)
            {

            }

        }

         void OnDestory()
         {
             Disconnect();
         }
        public void Disconnect()
        {
            mySocket.Async_Disconnect(CallBack_DisConnect);//断开连接
        }
         void CallBack_DisConnect(bool s, MySocket.Erro_Socket errorcode, string exception)
         {
             if (thread != null && errorcode == MySocket.Erro_Socket.SUCCESS)
             {
                 thread.Abort();
             }
             else
             {
                 Console.WriteLine("CallBack_DisConnect" + s + errorcode.ToString() + exception);
             }
         }


    }